package com.ys.service.hr.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ys.dto.AddDto;
import com.ys.entity.flow.YspModel;
import com.ys.entity.hr.TwlStock;
import com.ys.entity.hr.TwlStockTransfer;
import com.ys.entity.hr.TwlStockTransferDetail;
import com.ys.entity.sys.TsOrganizationInfo;
import com.ys.entity.sys.TsUserChange;
import com.ys.entity.sys.YsMenu;
import com.ys.entity.sys.YsProcInst;
import com.ys.enume.flow.FlowEnum;
import com.ys.enume.flow.YsProcInstEnum;
import com.ys.enume.hr.TwlStockChangeEnum;
import com.ys.enume.hr.TwlStockFrozenRunningEnum;
import com.ys.mapper.hr.HrMapper;
import com.ys.mapper.hr.TwlStockTransferDetailMapper;
import com.ys.mapper.hr.TwlStockTransferMapper;
import com.ys.service.flow.YspTaskService;
import com.ys.service.hr.TwlStockService;
import com.ys.service.hr.TwlStockTransferService;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.Flow;
import com.ys.vo.R;

@Service("twlStockTransferService")
public class TwlStockTransferServiceImpl implements TwlStockTransferService {

	@Autowired
	private HrMapper hrMapper;
	@Autowired
	private TwlStockTransferMapper twlStockTransferMapper;
	@Autowired
	private TwlStockTransferDetailMapper twlStockTransferDetailMapper;


	@Autowired
	private TwlStockService twlStockService;
	@Autowired
	private YspTaskService yspTaskService;
	/**
	 * 新增
	 * @param params
	 * @return
	 * @throws Exception
	 */
	@Override
	public R add(String bid, String orgidTo, String remark, String detailArr, Long menuId) throws Exception {
		
		if (bid == null || bid.length() == 0) {
			return R.error("单号不能为空");
		} else if(new TwlStockTransfer().setBid(bid).count() > 0) {
			return R.error("单号已存在");
		}
		
		if (orgidTo == null || orgidTo.length() == 0) {
			return R.error("所需部门编号不能为空");
		} else if(new TsOrganizationInfo().setOrgid(orgidTo).count() == 0) {
			return R.error("所需部门不存在");
		}
		
		/*
		 *  验证详情数据物料
		 *  1、编码不能为空
		 *  2、数量不能为空，且不能超过可用数量
		 */
		JSONArray detailJA = JSON.parseArray(detailArr);
		if (detailJA == null || detailJA.size() == 0) {
			return R.error("详情数据不能为空");
		}
		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			Long stockId = detailJO.getLong("stockId");
			if (stockId == null) {
				return R.error("库存ID不能为空");
			}

			Integer num = detailJO.getInteger("num");
			if (num == null) {
				return R.error("数量不能为空");
			} else if (num <= 0) {
				return R.error("数量必须为正");
			}
			
			TwlStock twlStock = new TwlStock().setId(stockId).queryFirst();
			if (num > twlStock.getNum()) {
				return R.error("【" + twlStock.getMaterialCode() + "】可用数量不足");
			}
		}
		
		String loginUserId = ShiroUtils.getUserId();
		TsUserChange tsUserChange = new TsUserChange().setUserId(loginUserId).setStatus(1).queryFirst();

		// 添加转移单
		TwlStockTransfer entity = null;
		{
			Integer effectStock = FlowEnum.EffectStock.NOT_EFFECT.value;
			Long createChangeId = tsUserChange.getId();
			entity = TwlStockTransfer.twlStockTransfer(bid, effectStock, createChangeId, orgidTo, remark, 1);
		}
		twlStockTransferMapper.insert(entity);
		
		// 添加转移明细
		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			Long stockId = detailJO.getLong("stockId");

			Integer num = detailJO.getInteger("num");
			
			String bidStockTransfer = bid;
			TwlStockTransferDetail twlStockTransferDetail = TwlStockTransferDetail.twlStockTransferDetail(bidStockTransfer, stockId, num, 1);
			twlStockTransferDetailMapper.insert(twlStockTransferDetail);
		}
		
		/*
		 * 流程初始化
		 */
		YsMenu ysMenu = new YsMenu().setId(menuId).queryFirst();
		if (ysMenu.getFlowModelId().longValue() != 0L) {
			YspModel yspModel = new YspModel().setId(ysMenu.getFlowModelId()).queryFirst();
			String codeModel = yspModel.getCode();
			String createUserId = ShiroUtils.getUserId();
			yspTaskService.init(codeModel, bid, createUserId);
		}
		return R.ok(AddDto.closeAndReload());
	}
	
	@Override
	@Transactional
	public R edit(String bid, String orgidTo, String remark, String detailArr, Long menuId) throws Exception {
		
		if (bid == null || bid.length() == 0) {
			return R.error("单号不能为空");
		} else if(new TwlStockTransfer().setBid(bid).count() > 0) {
			return R.error("单号已存在");
		}
		
		if (orgidTo == null || orgidTo.length() == 0) {
			return R.error("所需部门编号不能为空");
		} else if(new TsOrganizationInfo().setOrgid(orgidTo).count() == 0) {
			return R.error("所需部门不存在");
		}
		
		Integer stateFlow = yspTaskService.flowState(bid);
		if (stateFlow != YsProcInstEnum.StateFlow.INIT.value) {
			return R.error("非制单中数据，无法修改");
		}
		
		// 验证是否制单人
		YsProcInst entity = new YsProcInst().setBid(bid).queryFirst();
		if (!entity.getCreateUserId().equals(ShiroUtils.getUserId())) {
			return R.error("非制单人无法修改");
		}
		
		/*
		 *  验证详情数据物料
		 *  1、编码不能为空
		 *  2、数量不能为空，且不能超过可用数量
		 */
		JSONArray detailJA = JSON.parseArray(detailArr);
		if (detailJA == null || detailJA.size() == 0) {
			return R.error("详情数据不能为空");
		}
		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			Long stockId = detailJO.getLong("stockId");
			if (stockId == null) {
				return R.error("库存ID不能为空");
			}

			Integer num = detailJO.getInteger("num");
			if (num == null) {
				return R.error("数量不能为空");
			} else if (num <= 0) {
				return R.error("数量必须为正");
			}
			
			TwlStock twlStock = new TwlStock().setId(stockId).queryFirst();
			if (num > twlStock.getNum()) {
				return R.error("【" + twlStock.getMaterialCode() + "】可用数量不足");
			}
		}
		
		// 更新物料转移单
		TwlStockTransfer twlStockTransfer = new TwlStockTransfer().setBid(bid).queryFirst();
		twlStockTransfer.setOrgidTo(orgidTo)
			.setRemark(remark);
		twlStockTransferMapper.update(twlStockTransfer);

		// 删除旧的转移明细
		hrMapper.deleteTwlStockTransferDetailByBid(bid);
		
		// 添加转移明细
		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			Long stockId = detailJO.getLong("stockId");
			Integer num = detailJO.getInteger("num");
			String bidStockTransfer = bid;
			TwlStockTransferDetail twlStockTransferDetail = TwlStockTransferDetail.twlStockTransferDetail(bidStockTransfer, stockId, num, 1);
			twlStockTransferDetailMapper.insert(twlStockTransferDetail);
		}
		
		return R.ok(AddDto.gotoEdit("/web/hr/twlStockTransfer/toFlow?bid=" + bid));
	}

	@Override
	@Transactional
	public R deleteTrue(Long id) throws Exception {
//		if (id == null) {
//			return R.error("ID不能为空");
//		}
//		TccAllocate entity = new TccAllocate().setId(id).queryFirst();
//		if (entity.getEffectStock() == FlowEnum.EffectStock.EFFECTED.value) {
//			return R.error("已生效数据无法删除");
//		}
//		// 验证是否制单人
//		String loginUserId = ShiroUtils.getUserId();
//		TsUserChange tsUserChange = new TsUserChange().setId(entity.getCreateChangeId()).queryFirst();
//		
//		if (!tsUserChange.getUserId().equals(loginUserId)) {
//			return R.error("非制单人，无法删除");
//		}
//		
//		// 删除主数据
//		tccAllocateMapper.deleteTrue(id);
//		
//		// 删除子数据
//		List<TccAllocateDetail> listDetail = new TccAllocateDetail().setBidAllocate(entity.getBid()).queryList();
//		for(TccAllocateDetail detail : listDetail) {
//			tccAllocateDetailMapper.deleteTrue(detail.getId());
//		}
//		
//		yspTaskService.flowDelete(entity.getBid(), loginUserId);
		return R.ok();
	}

	@Override
	@Transactional
	public R flowPass(Long id, String loginUserId) throws Exception {
		
		TwlStockTransfer entity = new TwlStockTransfer().setId(id).queryFirst();
		String bid = entity.getBid();
		
		YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();
		
		// 若流程是初始化状态，需要验证库存并冻结
		List<TwlStockTransferDetail> listDetail = new TwlStockTransferDetail().setBidStockTransfer(entity.getBid()).queryList();
		if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
			for(TwlStockTransferDetail detail : listDetail) {
				Long stockId = detail.getStockId();
				Integer num = detail.getNum();
				
				TwlStock twlStock = new TwlStock().setId(stockId).queryFirst();
				if (num > twlStock.getNum()) {
					return R.error("【" + twlStock.getMaterialCode() + "】可用数量不足");
				}
			}
		}
		
		try {
			Flow f = yspTaskService.flowPass(bid, loginUserId);
			if (f.getCode() == Flow.Code.FAILED.value) {
				return R.error(f.getMsg());
			} else {
				// 若是制单流转，冻结账户
				if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
					for(TwlStockTransferDetail detail : listDetail) {
						
						// 冻结库存
						Long stockId = detail.getStockId();
						Integer type = TwlStockFrozenRunningEnum.Type.FROZEN_TRANSFER.value;
						String sourceBid = bid;
						Long sourceId = detail.getId();
						Integer frozenNum = detail.getNum();
						twlStockService.frozen(stockId, type, sourceBid, sourceId, frozenNum);
					}
				}
				
				if (f.getState() == Flow.State.FINISH.value) {
					flowFinish(id);
				}
				return R.ok();
			}
		} catch (Exception e) {
			e.printStackTrace();
			return R.error("服务器正在开小差，请联系客服");
		}
	}

	@Override
	public R flowRefuse(String bid, String reason, String loginUserId) throws Exception {
		
		TwlStockTransfer entity = new TwlStockTransfer().setBid(bid).queryFirst();
		
		R r = yspTaskService.flowRefuse(bid, reason, loginUserId);
		
		if (r.getCode() == R.Code.SUCCESS.value) {
			YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();
			// 若退回到制单状态，则解冻库存
			if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
				List<TwlStockTransferDetail> listDetail = new TwlStockTransferDetail().setBidStockTransfer(entity.getBid()).queryList();
				for(TwlStockTransferDetail detail : listDetail) {
					
					// 解冻库存
					Long stockId = detail.getStockId();
					Integer type = TwlStockFrozenRunningEnum.Type.UNFROZEN_TRANSFER.value;
					String sourceBid = bid;
					Long sourceId = detail.getId();
					Integer unfrozenNum = detail.getNum();
					twlStockService.unfrozen(stockId, type, sourceBid, sourceId, unfrozenNum);
				}
			}
		}
		return r;
	}



	@Override
	public R flowInit(String bid, String reason, String loginUserId) throws Exception {

		TwlStockTransfer entity = new TwlStockTransfer().setBid(bid).queryFirst();

		R r = yspTaskService.flowInit(bid, reason, loginUserId);

		if (r.getCode() == R.Code.SUCCESS.value) {
			YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();
			// 若退回到制单状态，则解冻库存
			if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
				List<TwlStockTransferDetail> listDetail = new TwlStockTransferDetail().setBidStockTransfer(entity.getBid()).queryList();
				for(TwlStockTransferDetail detail : listDetail) {

					// 解冻库存
					Long stockId = detail.getStockId();
					Integer type = TwlStockFrozenRunningEnum.Type.UNFROZEN_TRANSFER.value;
					String sourceBid = bid;
					Long sourceId = detail.getId();
					Integer unfrozenNum = detail.getNum();
					twlStockService.unfrozen(stockId, type, sourceBid, sourceId, unfrozenNum);
				}
			}
		}
		return r;
	}



	@Override
	@Transactional
	public void flowFinish(Long id) throws Exception {
		
		TwlStockTransfer entity = new TwlStockTransfer().setId(id).queryFirst();
		
		YsProcInst ysProcInst = new YsProcInst().setBid(entity.getBid()).queryFirst();
		if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.FINISH.value) {
			return;
		}
		
		entity.setEffectStock(FlowEnum.EffectStock.EFFECTED.value);
		twlStockTransferMapper.update(entity);

		List<TwlStockTransferDetail> listDetail = new TwlStockTransferDetail().setBidStockTransfer(entity.getBid()).queryList();
		for(TwlStockTransferDetail detail : listDetail) {
			
			// 解冻库存
			{
				Long stockId = detail.getStockId();
				Integer type = TwlStockFrozenRunningEnum.Type.UNFROZEN_TRANSFER.value;
				String sourceBid = entity.getBid();
				Long sourceId = detail.getId();
				Integer unfrozenNum = detail.getNum();
				twlStockService.unfrozen(stockId, type, sourceBid, sourceId, unfrozenNum);
			}
			
			// 库存变动
			{
				Long stockId = detail.getStockId();
				Integer type = TwlStockChangeEnum.Type.TRANSFER.value;
				String sourceBid = entity.getBid();
				Long sourceId = detail.getId();
				Integer sourceNum = detail.getNum();
				twlStockService.change(stockId, type, sourceId, sourceBid, sourceNum);
			}
		}
	}



	//获取列表数据
	@Override
	@Transactional
	public Map<String,Object> getExtraParam(String bid) throws Exception{
		Map<String,Object> entity = new TwlStockTransfer().setBid(bid).queryFirstMap();
		TsOrganizationInfo org = new TsOrganizationInfo().setOrgid(entity.get("orgidTo").toString()).queryFirst();

		entity.put("orgNameTo", org.getOrgName());
		return entity;
	}
	//获取子列表数据
	@Override
	@Transactional
	public List<Map<String, Object>> getItemList( String bid) throws Exception{
		// 子列表配置信息
		List<Map<String, Object>> sonlist = new TwlStockTransferDetail()
				.setBidStockTransfer(bid)

				.addLeftJoin("TWL_Stock B on B.Id = A.StockId")
				.addField("B.NumAll numStock, B.Remark stockRemark, B.Orgid orgid, B.CompanyVid companyVid, B.Orgid orgid")

				.addLeftJoin("TWL_StockInDetail B1 on B1.Id = B.StockInDetailId")
				.addField("B1.Price price, B1.BidStockIn bidStockIn, B1.Img img")

				.addLeftJoin("TS_OrganizationInfo B2 on B2.Orgid = B.Orgid")
				.addField("B2.OrgName orgName, B2.HeadUserId orgHeadUserId")

				.addLeftJoin("TB_CompanyInfo B3 on B3.Vid = B.CompanyVid")
				.addField("B3.Vname companyVname")

				.addLeftJoin("TB_Material C on C.Code = B.MaterialCode")
				.addField("C.Code materialCode, C.Name materialName, C.Remark materialRemark")
				.queryMap();
		return sonlist;
	}

}
